package com.expert.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.expert.Mapper.ProjectMapper;
import com.expert.constant.MessageConstant;
import com.expert.context.BaseContext;
import com.expert.enums.ProjectStatus;
import com.expert.exception.AddException;
import com.expert.pojo.*;
import com.expert.service.*;
import com.expert.vo.ProjectInfoVo;
import com.expert.vo.ProjectOptions;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: ProjectServiceImpl
 * @Author: cxs
 * @Date: 2024/03/20 15:03
 * @Description:
 **/
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper,Project> implements ProjectService {


    @Autowired
    UserService userService;

    @Autowired
    ExpertService expertService;
    @Autowired
    RabbitSendService rabbitSendService;
    @Autowired
    ExtractConditionService conditionService;
    @Autowired
    ExtractAvoidService avoidService;
    @Autowired
    ExtractResultService extractResultService;
    /**
     * 分页查询项目基本信息
     *
     * @param page          当前页
     * @param pageSize      每页条数
     * @param projectStatus 项目状态
     * @param projectName   项目名
     * @param beginTime     项目评审时间范围开始
     * @param endTime       项目评审时间范围结束
     * @return Result<Page < Project>>
     */
    @Override
    public Page<Project> pageProjectService(Integer page, Integer pageSize, Integer projectStatus, String projectName, LocalDateTime beginTime, LocalDateTime endTime) {
        Page<Project> dbProjectPage=new Page<>(page,pageSize);
        page(dbProjectPage,new LambdaQueryWrapper<Project>()
                .eq(projectStatus!=null,Project::getProjectStatus,projectStatus)
                .like(StringUtils.isNotEmpty(projectName),Project::getProjectName,projectName)
                .between(beginTime!=null&&endTime!=null,Project::getProjectReviewTime,beginTime,endTime)
                .orderByDesc(Project::getCreateTime));

        return getPageProject(dbProjectPage);
    }

    /**
     * 添加项目信息
     *
     * @param project 项目信息
     */
    @Override
    public void addProject(Project project) {
        if(project.getProjectReviewTime().isBefore(LocalDateTime.now())){
            throw new AddException(MessageConstant.PROJECT_REVIEW_TIME_ERROR);
        }
        if (project.getProjectReviewNumber()<=0){
            throw new AddException(MessageConstant.PROJECT_REVIEW_NUMBER_ERROR);
        }
        project.setProjectStatus(ProjectStatus.CREATE.getCode());
        Long id = BaseContext.getCurrentId();
        LocalDateTime time = LocalDateTime.now();
        project.setCreateUser(id);
        project.setUpdateUser(id);
        project.setUpdateTime(time);
        project.setCreateTime(time);
        this.save(project);
    }

    /**
     * 根据id获取项目信息
     *
     * @param id
     * @return
     */
    @Override
    public Project getProjectById(Long id) {
        return this.getById(id);
    }

    /**
     * 修改项目信息
     *
     * @param project
     */
    @Override
    public void updateProject(Project project) {
        if (project.getProjectStatus()>2){
            throw  new AddException(MessageConstant.PROJECT_UPDATE_STATUS_ERROR);
        }
        project.setUpdateTime(LocalDateTime.now());
        project.setUpdateUser(BaseContext.getCurrentId());
        this.updateById(project);
    }

    /**
     * 取消项目信息
     *
     * @param id
     */
    @Override
    public void cancelProject(Long id) {
        Project project = this.getById(id);
        if (project!=null){
            if (project.getProjectStatus()!=ProjectStatus.CANCEL.getCode()){
                this.lambdaUpdate()
                        .eq(Project::getId,id)
                        .set(Project::getProjectStatus,ProjectStatus.CANCEL.getCode())
                        .update();
                //如果有抽取条件则删除抽取条件
                List<Long> condition = this.conditionService.lambdaQuery()
                        .eq(ExtractCondition::getProjectId, id)
                        .list()
                        .stream().map(ExtractCondition::getId).toList();
                this.conditionService.removeBatchByIds(condition);
                //如果有回避条件就删除回避条件
                List<Long> avoid = this.avoidService.lambdaQuery()
                        .eq(ExtractAvoid::getProjectId, id)
                        .list()
                        .stream().map(ExtractAvoid::getId).toList();
                this.avoidService.removeBatchByIds(avoid);
                List<ExtractResult> extractResultList = this.extractResultService.lambdaQuery().eq(ExtractResult::getProjectId, id).list();
                extractResultList.forEach(result->{
                    Long expertId = result.getExpertId();
                    this.rabbitSendService.cancelProjectNotice(expertId,id);
                    this.removeById(result.getId());
                });
            }
        }
    }

    @Override
    public List<ProjectOptions> getProjectOptions() {

        List<Project> list = this.lambdaQuery().lt(Project::getProjectStatus, ProjectStatus.DRAWN.getCode()).list();
        List<ProjectOptions> optionsList = list.stream().map(item -> {
            ProjectOptions projectOptions = new ProjectOptions();
            BeanUtils.copyProperties(item, projectOptions);
            return projectOptions;
        }).toList();

        return optionsList;
    }

    @Override
    public ProjectInfoVo getProjectInfo(Long id) {
        Project project = this.getById(id);
        ProjectInfoVo projectInfoVo=new ProjectInfoVo();
        if (project!=null) {
            User user = this.userService.getById(project.getCreateUser());
            BeanUtils.copyProperties(project,projectInfoVo);
            projectInfoVo.setCreateUserName(user.getName());
        }
        return projectInfoVo;
    }

    @Override
    public Page<Project> pageExtractProjectService(Integer page, Integer pageSize, Integer projectStatus, String projectName, LocalDateTime beginTime, LocalDateTime endTime) {
        Page<Project> dbProjectPage=new Page<>(page,pageSize);
        page(dbProjectPage,new LambdaQueryWrapper<Project>()
                .between(Project::getProjectStatus,2,4)
                .eq(projectStatus!=null,Project::getProjectStatus,projectStatus)
                .like(StringUtils.isNotEmpty(projectName),Project::getProjectName,projectName)
                .between(beginTime!=null&&endTime!=null,Project::getProjectReviewTime,beginTime,endTime)
                .orderByDesc(Project::getCreateTime));
        return getPageProject(dbProjectPage);
    }

    /**
     * 获取项目信息
     *
     * @param id
     * @return
     */
    @Override
    public ProjectInfoVo getProjectInfoById(Long id) {
        Project project = this.getProjectById(id);
        User user = this.userService.getById(project.getCreateUser());
        ProjectInfoVo projectInfoVo=new ProjectInfoVo();
        BeanUtils.copyProperties(project,projectInfoVo);
        projectInfoVo.setCreateUserName(user.getName());
        return projectInfoVo;
    }

    /**
     * 封装信息
     * @param dbProjectPage
     * @return
     */
    private Page<Project> getPageProject(Page<Project> dbProjectPage) {
        Page<Project> projectPage=new Page<>();
        BeanUtils.copyProperties(dbProjectPage,projectPage);
        List<Project> records = dbProjectPage.getRecords().stream().map(item -> {
            Project project = new Project();
            BeanUtils.copyProperties(item, project);
            project.setProjectContent(null);
            return project;
        }).toList();
        projectPage.setRecords(records);
        return projectPage;
    }
}
